/*
This is part of Screenbar, which is based in part on the Litestep
shell source code.

Copyright (C) 2008-2009 Jim Babcock
Copyright (C) 1997-2009 The LiteStep Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "stdafx.h"

/////////////////////////////////////////////////////////////////////////////

Alignment parseAlign(const string &str)
{
	if(!_stricmp(str.c_str(), "center"))
		return alignCenter;
	else if(!_stricmp(str.c_str(), "left"))
		return alignLeft;
	else if(!_stricmp(str.c_str(), "right"))
		return alignRight;
	else if(!_stricmp(str.c_str(), "top"))
		return alignTop;
	else if(!_stricmp(str.c_str(), "bottom") || !_stricmp(str.c_str(), "bot"))
		return alignBottom;
	else
		return alignCenter;
}

/////////////////////////////////////////////////////////////////////////////

LayoutCacheNode::LayoutCacheNode(const LayoutCacheNode &copy)
{
	visited = false;
	element = copy.element;
	context = copy.context;
	parent = NULL;
	elementData = NULL;
	refcount = 0;
	
	for(unsigned ii=0; ii<children.size(); ii++) {
		LayoutCacheNode *child = new LayoutCacheNode(*copy.children[ii]);
		child->parent = this;
		children.push_back(child);
	}
}

LayoutCacheNode::LayoutCacheNode(Layout *owner, LayoutElement *element, const ElementContext *context, SizeFallback *sizeFallback)
{
	this->element = element;
	this->context = *context;
	this->owner = owner;
	this->parent = NULL;
	this->visited = false;
	this->elementData = NULL;
	this->refcount = 0;
}

LayoutCacheNode::~LayoutCacheNode()
{
	if(elementData)
		element->deleteElementData(this, elementData);
}

LayoutLocation ScreenbarPanel::elementAtPoint(int x, int y)
{
	LayoutLocation ret;
	
	LayoutReference *ref = layout->elementAtPoint(x, y);
	LayoutCacheNode *node = ref->getNode();
	ret.context = node->context;
	ret.element = node->element;
	delete ref;
	
	return ret;
}

LayoutCacheNode *LayoutCacheNode::elementAtPoint(int x, int y)
{
	LayoutCacheNode *pos = this;
	LayoutCacheNode *next;
	
	do {
		next = NULL;
		for(int ii=pos->children.size()-1; ii>=0; ii--)
		{
			LayoutCacheNode *child = pos->children[ii];
			if(child->boundingRect.containsPoint(x, y)) {
				next = child;
				break;
			}
		}
		if(next)
			pos = next;
	} while(next);
	
	return pos;
}

void LayoutCacheNode::traverse(vector<LayoutCacheNode*> &visitedNodes)
{
	visitedNodes.push_back(this);
	for(unsigned ii=0; ii<children.size(); ii++)
		children[ii]->traverse(visitedNodes);
}

LayoutCacheNode *LayoutCacheNode::findSuffix(string suffix)
{
	LayoutCacheNode *pos = this;
	
	while(pos)
	{
		string varname = pos->element->prefix + suffix;
		if(rcIsDefined(varname.c_str())) {
			string var = getConfigLine(varname.c_str(), "", "");
			if(var != "")
				return pos;
		}
		
		pos = pos->parent;
	}
	
	return NULL;
}

/////////////////////////////////////////////////////////////////////////////

void printLayout(LayoutCacheNode *node, int indentLevel)
{
	for(int ii=0; ii<indentLevel; ii++)
		trace << "    ";
	
	trace << node->element->prefix << " (" << (int)node << ") "<<node->boundingRect.toString()<<"\n";
	
	for(unsigned ii=0; ii<node->children.size(); ii++)
		printLayout(node->children[ii], indentLevel+1);
}

